﻿<!DOCTYPE html>
<html>
<head>
<title>第6章 流的破坏与保护</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
/* Author: Nicolas Hery - http://nicolashery.com */
/* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */
/* Source: https://github.com/nicolahery/markdownpad-github */

/* RESET
=============================================================================*/

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
}

/* BODY
=============================================================================*/

body {
  font-family: Helvetica, arial, freesans, clean, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  color: #333;
  background-color: #fff;
  padding: 20px;
  max-width: 960px;
  margin: 0 auto;
}

@media screen and (max-width: 768px) {
  body {
  	font-size: 20px !important;
  }
}

body>*:first-child {
  margin-top: 0 !important;
}

body>*:last-child {
  margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
  margin: 16px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
  font-size: inherit;
}

h1 {
  font-size: 28px;
}

h1:first-of-type {
  font-size: 32px;
  text-align: center;
}

h2 {
  font-size: 26px;
}

h3 {
  font-size: 22px;
}

h4 {
  font-size: 18px;
}

h5 {
  font-size: 16px;
}

h6 {
  font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
  margin-top: 0;
  padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
  margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
  color: #4183C4;
  text-decoration: none;
}

a:hover {
  color: #d0782a;
  text-decoration: underline;
}

a:active {
  color: #bd4147;
}

/* LISTS
=============================================================================*/

ul, ol {
  padding-left: 30px;
}

ul li > :first-child, 
ol li > :first-child, 
ul li ul:first-of-type, 
ol li ol:first-of-type, 
ul li ol:first-of-type, 
ol li ul:first-of-type {
  margin-top: 0px;
  margin-bottom: 0px;
}

ul ul, ul ol, ol ol, ol ul {
  margin-bottom: 0;
}

dl {
  padding: 0;
}

dl dt {
  font-size: 14px;
  font-weight: bold;
  font-style: italic;
  padding: 0;
  margin: 15px 0 5px;
}

dl dt:first-child {
  padding: 0;
}

dl dt>:first-child {
  margin-top: 0px;
}

dl dt>:last-child {
  margin-bottom: 0px;
}

dl dd {
  margin: 0 0 15px;
  padding: 0 15px;
}

dl dd>:first-child {
  margin-top: 0px;
}

dl dd>:last-child {
  margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
  font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
  margin: 0 0px;
  padding: 0px 3px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #eee;
  color: #00d;
  border-radius: 3px;
}

pre>code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent;
}

pre {
  background-color: #f8f8f8;
  border: 1px solid #ccc;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px;
}

pre code, pre tt {
  background-color: transparent;
  border: none;
}

kbd {
    -moz-border-bottom-colors: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    background-color: #DDDDDD;
    background-image: linear-gradient(#F1F1F1, #DDDDDD);
    background-repeat: repeat-x;
    border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
    border-image: none;
    border-radius: 2px 2px 2px 2px;
    border-style: solid;
    border-width: 1px;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    line-height: 16px;
    padding: 1px 4px;
}

/* QUOTES
=============================================================================*/
blockquote {
  border-left: 4px solid #42b983;
  padding: 0 15px;
  color: #d1d9e1;
  background: #474949;
}

blockquote>:first-child {
  margin-top: 0px;
}

blockquote>:last-child {
  margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
  clear: both;
  margin: 15px 0;
  height: 0px;
  overflow: hidden;
  border: none;
  background: transparent;
  border-bottom: 4px solid #ddd;
  padding: 0;
}

/* TABLES
=============================================================================*/
table {
	margin: 0 auto;
	border-collapse: collapse;
	width: 100%;
	box-sizing: border-box;
	margin-bottom: 30px;
	
}

table th, table td {
  border: 1px solid #ccc;
  padding: 6px 13px; 
}

table th {
  font-weight: bold;
  text-align: center !important;
  background-color: #9ec68e;
}

table tr {
  border-top: 1px solid #ccc;
  background-color: #fff;
}

table tr:nth-child(2n) {
  background-color: #dff0d8;
}

/* IMAGES
=============================================================================*/
img {
  max-width: 100%;
}

p > img {
  display: table;
  margin: 0 auto;
}
</style>
<style type="text/css">
.highlight  { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.pl-c {
    color: #969896;
}

.pl-c1,.pl-mdh,.pl-mm,.pl-mp,.pl-mr,.pl-s1 .pl-v,.pl-s3,.pl-sc,.pl-sv {
    color: #0086b3;
}

.pl-e,.pl-en {
    color: #795da3;
}

.pl-s1 .pl-s2,.pl-smi,.pl-smp,.pl-stj,.pl-vo,.pl-vpf {
    color: #333;
}

.pl-ent {
    color: #63a35c;
}

.pl-k,.pl-s,.pl-st {
    color: #a71d5d;
}

.pl-pds,.pl-s1,.pl-s1 .pl-pse .pl-s2,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre,.pl-src,.pl-v {
    color: #df5000;
}

.pl-id {
    color: #b52a1d;
}

.pl-ii {
    background-color: #b52a1d;
    color: #f8f8f8;
}

.pl-sr .pl-cce {
    color: #63a35c;
    font-weight: bold;
}

.pl-ml {
    color: #693a17;
}

.pl-mh,.pl-mh .pl-en,.pl-ms {
    color: #1d3e81;
    font-weight: bold;
}

.pl-mq {
    color: #008080;
}

.pl-mi {
    color: #333;
    font-style: italic;
}

.pl-mb {
    color: #333;
    font-weight: bold;
}

.pl-md,.pl-mdhf {
    background-color: #ffecec;
    color: #bd2c00;
}

.pl-mdht,.pl-mi1 {
    background-color: #eaffea;
    color: #55a532;
}

.pl-mdr {
    color: #795da3;
    font-weight: bold;
}

.pl-mo {
    color: #1d3e81;
}
.task-list {
padding-left:10px;
margin-bottom:0;
}

.task-list li {
    margin-left: 20px;
}

.task-list-item {
list-style-type:none;
padding-left:10px;
}

.task-list-item label {
font-weight:400;
}

.task-list-item.enabled label {
cursor:pointer;
}

.task-list-item+.task-list-item {
margin-top:3px;
}

.task-list-item-checkbox {
display:inline-block;
margin-left:-20px;
margin-right:3px;
vertical-align:1px;
}
</style>
<base target=_blank>
</head>
<body>
<h1 id="-6-">第6章 流的破坏与保护</h1>
<h2 id="-float-">魔鬼属性<code>float</code></h2>
<h3 id="-float-"><code>float</code>的本质与特性</h3>
<p><strong><code>float</code>浮动属性让父元素高度坍塌的原因就是为了实现文字环绕效果</strong>。</p>
<p><code>float</code>自身特性：</p>
<ul>
<li>包裹性；</li><li>块状化并格式化上下文；</li><li>破坏文档流；</li><li>没有任何<code>margin</code>合并。</li></ul>
<p>包裹性，由<strong>包裹</strong>和<strong>自适应性</strong>两部分组成。</p>
<ol>
<li><strong>包裹</strong>。浮动元素父元素宽度<code>200px</code>，子元素是一个宽度<code>128px</code>宽度的图片，则此时浮动元素宽度表现为<strong>包裹</strong>，就是里面图片的宽度<code>128px</code>。</li></ol>
<p><img src="https://i.imgur.com/QCNBDxs.jpg" alt=""></p>
<ol>
<li><strong>自适应性</strong>。</li></ol>
<p><strong>块状化</strong>，元素一旦<code>float</code>的属性值不为<code>none</code>，则其<code>display</code>计算值为<code>block</code>或<code>table</code>。<strong><code>text-align</code>对浮动元素无效。</strong></p>
<table>
<thead>
<tr>
<th>设定值</th>
<th>计算值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>inline</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>inline-block</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>inline-table</code></td>
<td><code>table</code></td>
</tr>
<tr>
<td><code>table-row</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>table-row-group</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>table-column</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>table-columngroup</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>table-cell</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>table-caption</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>table-header-group</code></td>
<td><code>block</code></td>
</tr>
<tr>
<td><code>table-footer-group</code></td>
<td><code>block</code></td>
</tr>
</tbody>
</table>
<h2 id="-float-"><code>float</code>的作用机制</h2>
<p><strong>文字环绕效果</strong>是由两个特性（<strong>父级高度坍塌</strong>和<strong>行框盒子区域限制</strong>）共同作用的结果，定高只能解决<strong>父级元素高度坍塌</strong>带来的影响，但是对<strong>行框盒子区域限制</strong>没有任何效果，结果导致的问题是浮动元素垂直区域一旦超出高度范围，或下面元素<code>margin-top</code>负值上偏移，就很容易使后面的元素发生“环绕效果”。</p>
<h2 id="-float-"><code>float</code>更深入的作用机制</h2>
<p><strong>浮动元素和内联元素在一行显示。</strong></p>
<ul>
<li><strong>浮动锚点</strong>是<code>float</code>元素所在的<strong>流</strong>中的一个点，这个点本身并不浮动。其作用是产生<strong>行框盒子</strong>，因为<strong>浮动锚点</strong>表现如同一个空的内联元素，有内联元自然就有<strong>行框盒子</strong>。</li><li><strong>浮动参考</strong>指的是浮动元素对齐参考的实体。</li></ul>
<p><code>float</code>元素的<strong>浮动参考</strong>是<strong>行框盒子</strong>，也就是<code>float</code>元素在当前<strong>行框盒子</strong>内定位。</p>
<h2 id="-float-"><code>float</code>与流体布局</h2>
<p><p data-height="265" data-theme-id="0" data-slug-hash="YjrGyL" data-default-tab="css,result" data-user="whjin" data-pen-title="中间内容居中的左中右布局" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/YjrGyL/">中间内容居中的左中右布局</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<h1 id="-float-clear-"><code>float</code>的天然克星<code>clear</code></h1>
<h2 id="-clear-">什么是<code>clear</code>属性</h2>
<p><code>clear</code>专门用来处理<code>float</code>属性带来的高度坍塌等问题。</p>
<pre><code>clear: none | left | right | both
</code></pre><ul>
<li><code>none</code>：默认值，左右浮动</li><li><code>left</code>：左侧抗浮动</li><li><code>right</code>：右侧抗浮动</li><li><code>both</code>：两侧抗浮动</li></ul>
<p>实际应用中只使用<code>clear:both;</code>即可。</p>
<h2 id="-clear-">成事不足败事有余的<code>clear</code></h2>
<p><code>clear</code>属性只有块级元素才有效，而<code>:after</code>等伪元素默认都是内联水平，这就是伪元素清除浮动影响时需要设置<code>display</code>属性值的原因。</p>
<p><code>clear:both</code>的作用本质是让自身不与<code>float</code>元素在一行显示，并不是真正意义上的清除浮动。</p>
<ol>
<li>如果<code>clear:both;</code>元素前面的元素就是<code>float</code>元素，则<code>margin-top</code>负值即使设成<code>-9999px</code>，也没有效果。</li><li><code>clear:both;</code>后面的元素依旧可能发生文字环绕的现象。</li></ol>
<h1 id="css-bfc-">CSS世界的结界——<strong>BFC</strong></h1>
<h2 id="-bfc-"><strong>BFC</strong>的定义</h2>
<p><strong>BFC</strong>称为<strong>块级格式化上下文</strong>。<strong>BFC</strong>元素不可能发生<code>margin</code>重叠，<code>margin</code>重叠会影响外面的元素；<strong>BFC</strong>元素也可以用来清除浮动的影响，如果不清楚，子元素浮动则会父元素高度坍塌，必然会影响后面元素布局和定位。</p>
<p>何时会触发<strong>BFC</strong>，常见情况如下：</p>
<ul>
<li><code>html</code>根元素；</li><li><code>overflow</code>的值为<code>auto</code>、<code>scroll</code>或<code>hidden</code>；</li><li><code>display</code>的值为<code>table-cell</code>、<code>table-caption</code>和<code>inline-block</code>中的任何一个；</li><li><code>float</code>的值不为<code>none</code>；</li><li><code>position</code>的值不为<code>relative</code>和<code>static</code>。</li></ul>
<p>只要元素符合上面任意一个条件，就无须使用<code>clear:both;</code>属性去清除浮动的影响。</p>
<h2 id="-bfc-"><strong>BFC</strong>与流体布局</h2>
<p><strong>BFC</strong>的表现原则：具有<strong>BFC</strong>特性的元素的子元素不会受到外部元素的影响，也不会影响外部元素。普通流体元素在设置了<code>overflow:hidden;</code>后，会自动填满容器中除了浮动元素以外的剩余空间，形成自适应布局效果。</p>
<pre><code>img {
    float: left;
    margin-right: 10px;
}

.content {
    overflow: hidden;
}
</code></pre><p>基于<strong>BFC</strong>特性的自适应布局有如下优点：</p>
<ol>
<li>自适应内容由于封闭更加健壮，容错性更强。内部设置<code>clear:both;</code>不会与<code>float</code>元素相互干扰而导致错位。</li><li>自适应内容自动填充浮动以外区域，无需关心浮动元素宽度，可以整站大规模应用。</li></ol>
<pre><code>.left {
    float: left;
}

.right {
    float: right;
}

.bfc {
    overflow: hidden;
}
</code></pre><ol>
<li><code>float:left;</code>。浮动元素本身<strong>BFC</strong>化，然而浮动元素具有破坏性和包裹性，失去了元素本身的流体自适应性，因此无法用来实现自动填满容器的自适应布局。</li><li><code>position:absolute;</code>。脱离文档流，不容易操作。</li><li><strong><code>overflow:hidden;</code>块状元素的流体特性保存得很好，加上</strong>BFC<strong>的独立区域特性，而且从IE7开始就支持，兼容性很好。唯一的问题是容器盒子外的元素可能会被隐藏掉。</strong></li><li><code>display:inline-block;</code></li><li><code>display:table-cell</code></li><li><code>display:table-row</code></li><li><code>display:table-caption</code></li></ol>
<p>总结上面的自适应布局设置，最佳实践如下：</p>
<ol>
<li><code>overflow: auto/hidden;</code>，适用于IE7及以上版本浏览器；</li><li><code>display: inline-block;</code>，适应于IE6和IE7;</li><li><code>display: table-cell;</code>，适用于IE8及以上版本浏览器。</li></ol>
<p>IE7及以上版本浏览器适配的自适应解决方案：</p>
<ol>
<li>借助<code>overflow</code>属性，如下:<pre><code>.lbf-content {
 overflow: hidden;
}
</code></pre></li><li>融合<code>display: table-cell;</code>和<code>display: inline-block;</code>，如下：<pre><code>.lbf-content {
 display: table-cell;
 width: 9999px;
}
</code></pre></li></ol>
<p><code>display: table-cell;</code>元素内连续英文字符无法换行的问题：</p>
<pre><code>.word-break {
    display: table;
    width: 100%;
    table-layout: fixed;
    word-break: break-all;
}
</code></pre><h1 id="-overflow-">最佳结界<code>overflow</code></h1>
<blockquote>
<p>要彻底清除浮动的影响，最适合的属性是<code>overflow</code>。<code>overflow:hidden;</code>声明不会影响元素原先的流体特性或宽度表现。</p>
</blockquote>
<h2 id="-overflow-border-box-"><code>overflow</code>裁剪界线<code>border box</code></h2>
<p>当子元素内容超出容器宽度高度限制的时候，剪裁的边界是<code>border box</code>的内边缘，而非<code>padding box</code>的内边缘。</p>
<p>在实际项目开发时，要尽量避免滚动条容器设置<code>padding-bottom</code>值。</p>
<h2 id="-overflow-x-overflow-y-">了解<code>overflow-x</code>和<code>overflow-y</code></h2>
<p>IE8以上浏览器，<code>overflow</code>增加了两个属性，<code>overflow-x</code>和<code>overflow-y</code>，分别表示单独控制水平或垂直方向上的剪裁规则。</p>
<p>支持的属性值和<code>overflow</code>属性一模一样：</p>
<ul>
<li><code>visible</code>：默认值</li><li><code>hidden</code>：剪裁</li><li><code>scroll</code>：滚动条</li><li><code>auto</code></li></ul>
<p><strong>不会出现一个方向溢出剪裁或滚动，另一个方向内容溢出显示的效果。</strong></p>
<h2 id="-overflow-"><code>overflow</code>与滚动条</h2>
<p>浏览器的滚动条：</p>
<ol>
<li>默认滚动条来自<code>html</code>，而不是<code>body</code>标签。去除页面默认滚动条：<pre><code>html {
 overflow: hidden;
}
</code></pre>在PC端，滚动条高度可以使用<code>document.documentElement.scrollTop</code>获取，但是在移动端，需要使用<code>document.body.scrollTop</code>获取。</li><li>滚动条会占用容器的可用高度或宽度。</li></ol>
<p><strong>让页面滚动条不发生晃动的技巧</strong></p>
<pre><code>html {
    overflow-y: scroll;
}

:root {
    overflow-y: auto;
    overflow-x: hidden;
}

:root body {
    position: absolute;
}

body {
    width: 100%;
    overflow: hidden;
}
</code></pre><p>滚动条自定义效果：</p>
<ul>
<li>整体部分：<code>::-webkit-scrollbar</code></li><li>两端按钮：<code>::-webkit-scrollbar-button</code></li><li>外层轨道：<code>::-webkit-scrollbar-track</code></li><li>内层轨道：<code>::-webkit-scrollbar-track-piece</code></li><li>滚动滑块：<code>::-webkit-scrollbar-thumb</code></li><li>边角：<code>::-webkit-scrollbar-corner</code></li></ul>
<pre><code>::-webkit-scrollbar { /*血槽宽度*/
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-thumb { /*拖动条*/
    background-color: rgba(0, 0, 0, .3);
    border-radius: 6px;
}

::-webkit-scrollbar-track { /*背景槽*/
    background-color: #ddd;
    border-radius: 6px;
}
</code></pre><h2 id="-overflow-">依赖<code>overflow</code>的样式表现</h2>
<p>单行文字溢出<code>...</code>效果，需要使用到<code>overflow:hidden;</code>、<code>text-overflow:hidden;</code>，效果实现必需的3个声明如下：</p>
<pre><code>.ell {
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
}
</code></pre><p>最多显示2行内容，再多就打点的核心CSS代码：</p>
<pre><code>.ell-rows-2 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}
</code></pre><h2 id="-overflow-"><code>overflow</code>与锚点定位</h2>
<p>基于URL地址的锚链<code>location.hash</code>实现锚点跳转的方法有两种：</p>
<ol>
<li><code>a</code>标签以及<code>name</code>属性</li><li>使用标签的<code>id</code>属性</li></ol>
<pre><code>&lt;a href=&quot;#1&quot;&gt;发展历程&lt;/a&gt;
&lt;a name=&quot;1&quot;&gt;&lt;/a&gt;
</code></pre><p><strong>1. 锚点定位行为的触发条件</strong></p>
<ol>
<li>URL地址中的锚链与锚点元素对应并有交互行为；</li><li>可<code>focus</code>的锚点元素处于<code>focus</code>状态。</li></ol>
<p><strong><code>focus</code>锚点定位</strong>指的是类似链接或按钮、输入框等可以被<code>focus</code>的元素在被<code>focus</code>时发生的页面重定位现象。</p>
<p><strong>URL地址锚点定位</strong>是让元素定位在浏览器窗体的上边缘，而<code>`focus</code>锚点定位`是让元素在浏览器窗体范围内显示即可。</p>
<p><strong>2. 锚点定位作用的本质</strong></p>
<p>锚点定位行为的发生，本质上是通过改变容器滚动高度或宽度来实现。改变了<code>scrollTop</code>或<code>scrollLeft</code>的值。</p>
<p><p data-height="300" data-theme-id="0" data-slug-hash="bjYKPW" data-default-tab="css,result" data-user="whjin" data-pen-title="窗体无跳动选项卡" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/bjYKPW/">窗体无跳动选项卡</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<p>处理列表部分区域正在浏览器外面依然会跳动的问题：</p>
<pre><code>$(&#39;label.click&#39;).removeAttribute(&#39;for&#39;).on(&#39;click&#39;, function () {
    $(&#39;.box&#39;).scrollTop(xxx);//滚动数值
});
</code></pre><p>基于父容器自身的<code>scrollTop</code>值改变来实现自定义滚动条效果。</p>
<ol>
<li>实现简单，无须做边界判断。<code>container.scrollTop=99999;</code>，列表滚动就是<code>scrollTop</code>值，实时获取。</li><li>可与原生的<code>scroll</code>事件天然继承，无缝对接。</li><li>无须改变子元素的结构。</li></ol>
<h1 id="-float-position-absolute-"><code>float</code>的兄弟<code>position:absolute</code></h1>
<p>绝对定位<code>absolute</code>具有块状化，块状格式化上下文、包裹性和自适应性。自适应性的最大宽度由“包含块”决定。</p>
<h2 id="-absolute-"><code>absolute</code>的包含块</h2>
<p>普通元素的百分比宽度是相对于父元素的<code>content box</code>宽度计算，而绝对定位元素的宽度是相对于第一个<code>position</code>不为<code>static</code>的祖先元素计算的。</p>
<ol>
<li>根元素<code>html</code>被称为“初始包含块”，其尺寸等同于浏览器可视窗口的大小。</li><li>对于其他元素，如果该元素的<code>position</code>是<code>relative</code>或<code>static</code>，则“包含块”由其最近的块容器祖先盒子的<code>content box</code>边界组成。</li><li>如果元素<code>position:fixed;</code>，则“包含块”是“初始包含块”。</li><li>如果元素<code>position:absolute;</code>，则“包含块”由最近的<code>position</code>不为<code>static</code>的祖先元素建立，具体方式如下：<br> <strong>如果该祖先元素是纯<code>inline</code>元素，则规则略复杂：</strong> <ul>
<li>给内联元素的前后各生成一个宽度为<code>0</code>的内联盒子，则这两个内联盒子的<code>padding box</code>外面的包围盒子就是内联元素的“包含块”。</li><li>如果该内联元素被跨行分割，则<strong>包含块</strong>是未定义的。<br><strong>否则，“包含块”由该祖先的<code>padding box</code>边界组成。</strong></li></ul>
</li></ol>
<p>和常规元素相比，绝对定位元素的<strong>包含块</strong>有3个明显的差异：</p>
<ol>
<li>内联元素也可以作为<strong>包含块</strong>所在的元素；</li><li><strong>包含块</strong>所在的元素不是父级块元素，而是最近的<code>position</code>不为<code>static</code>的祖先元素或根元素；</li><li>边界是<code>padding box</code>而不是<code>content box</code>。</li></ol>
<p><strong>内联元素的“包含块”是由“生成的”前后内联盒子决定，与里面的内联盒子细节没有任何关系。</strong></p>
<blockquote>
<p><code>height:100%;</code>是第一个具有定位属性值得祖先元素的高度，而<code>height:inherit;</code>则是单纯的父元素的高度继承。</p>
</blockquote>
<h2 id="-absolute-">具有相对特性的无依赖<code>absolute</code>绝对定位</h2>
<p><strong>1. 各类图标定位</strong></p>
<p><p data-height="265" data-theme-id="0" data-slug-hash="jpYJJp" data-default-tab="css,result" data-user="whjin" data-pen-title="无依赖绝对定位”与导航图标定位" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/jpYJJp/">无依赖绝对定位”与导航图标定位</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<p><p data-height="265" data-theme-id="0" data-slug-hash="vapMWW" data-default-tab="css,result" data-user="whjin" data-pen-title="文字和图片水平对齐" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/vapMWW/">文字和图片水平对齐</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<p><strong>2. 超越常规布局的排版</strong></p>
<p><p data-height="365" data-theme-id="0" data-slug-hash="bjayad" data-default-tab="css,result" data-user="whjin" data-pen-title="“无依赖绝对定位”与超越常规布局的排版" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/bjayad/">“无依赖绝对定位”与超越常规布局的排版</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<p><strong>3. 下拉列表的定位</strong></p>
<p><p data-height="300" data-theme-id="0" data-slug-hash="NBXVVR" data-default-tab="css,result" data-user="whjin" data-pen-title="“无依赖绝对定位”与下拉列表定位" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/NBXVVR/">“无依赖绝对定位”与下拉列表定位</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


<p><strong>4. 占位符效果模拟</strong></p>
<p><strong>5. 进一步深入“无依赖绝对定位”</strong></p>
<h2 id="-absolute-text-align-"><code>absolute</code>与<code>text-align</code></h2>
<p><code>absolute</code>元素的<code>display</code>计算值是块状的，<code>text-align</code>不会起作用。</p>
<p><p data-height="265" data-theme-id="0" data-slug-hash="XBZmdB" data-default-tab="css,result" data-user="whjin" data-pen-title="absolute与text-align互相作用" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/XBZmdB/">absolute与text-align互相作用</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<p><p data-height="265" data-theme-id="0" data-slug-hash="NByxwE" data-default-tab="css,result" data-user="whjin" data-pen-title="主结构右外侧固定定位" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/NByxwE/">主结构右外侧固定定位</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<h1 id="-absolute-overflow-"><code>absolute</code>与<code>overflow</code></h1>
<p>如果<code>overflow</code>不是定位元素，同时绝对定位元素和<code>overflow</code>容器之间也没有定位元素，则<code>overflow</code>无法对<code>absolute</code>元素进行裁剪。<strong><code>overflow</code>元素父级是定位元素也不会裁剪。</strong></p>
<ol>
<li><code>overflow</code>属性所在的元素同时也是定位元素，里面的绝对定位元素会被裁剪；</li><li><code>overflow</code>元素和绝对定位元素之间有定位元素，也会被裁剪。</li><li><code>overflow</code>属性值不是<code>hidden</code>，而是<code>auto</code>或<code>scroll</code>，即使绝对定位元素高度比<code>overflow</code>元素高度大，也不会出现滚动条。</li></ol>
<h1 id="-absolute-clip-"><code>absolute</code>与<code>clip</code></h1>
<p><code>clip</code>属性要起作用，元素必须是绝对定位<code>absolute</code>或固定定位<code>fixed</code>。</p>
<p><code>clip</code>属性语法：<code>clip: rect(top right bottom left)</code></p>
<h2 id="-clip-">重新认识的<code>clip</code>属性</h2>
<p><strong>1. <code>fixed</code>固定定位的剪裁</strong></p>
<pre><code>.fixed-clip {
    position: fixed;
    clip: rect(30px 200px 200px 20px);
}
</code></pre><p><strong>2. 最佳可访问性隐藏</strong></p>
<p>最佳可访问性隐藏指的是视觉上看不见，但是辅助设备能够进行识别和访问。</p>
<pre><code>.logo h1 {
    position: absolute;
    clip: rect(0 0 0 0);
}
&lt;a href=&quot;/&quot; class=&quot;logo&quot;&gt;
    &lt;h1&gt;我是标题&lt;/h1&gt;
&lt;/a&gt;
</code></pre><h2 id="-clip-">深入了解<code>clip</code>的渲染</h2>
<p>clip隐藏仅仅是决定了哪部分是可见的，非可见部分无法响应点击事件，虽然视觉上隐藏，但是元素的尺寸依旧是原来的尺寸。</p>
<h1 id="-absolute-"><code>absolute</code>的流体特性</h1>
<h2 id="-absolute-left-top-right-bottom-">当<code>absolute</code>遇到<code>left/top/right/bottom</code>属性</h2>
<p>当<code>absolute</code>遇到<code>left/top/right/bottom</code>属性时，<code>absolute</code>元素才真正变成绝对定位元素。</p>
<h2 id="-absolute-"><code>absolute</code>的流体特性</h2>
<p>当一个绝对定位元素，其对立定位方向属性同时具有定位数值时，就会发生流体特性。</p>
<p><strong>普通元素流体特性只有水平方向（默认），但是绝对定位元素可以让垂直方向和水平方向同时保持流动性。</strong></p>
<h2 id="-absolute-margin-auto-"><code>absolute</code>的<code>margin:auto</code>居中</h2>
<pre><code>.box {
    width: 200px;
    height: 200px;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
}
</code></pre><h1 id="-position-relative-"><code>position:relative</code>才是大哥</h1>
<h2 id="-relative-absolute-"><code>relative</code>对<code>absolute</code>的限制</h2>
<h2 id="-relative-"><code>relative</code>与定位</h2>
<p><code>relative</code>与定位特性：一是相对自身，二是无侵入（当<code>relative</code>进行定位偏移时，不会影响周围元素的布局）。</p>
<p><code>relative</code>定位：相对定位元素的<code>left/top/right/bottom</code>百分比值是相对于 包含块计算，而非自身。</p>
<p><code>top/bottom</code>垂直方向的百分比值计算和<code>height</code>百分比值一样，都是相对于高度计算。</p>
<p>当相对定位元素同时应用对立方向定位值，<code>top/bottom</code>和<code>left/right</code>同时使用时，其表现和绝对定位差异很大，只有一个方向的定位属性起作用。</p>
<h2 id="-relative-"><code>relative</code>的最小化影响原则</h2>
<ol>
<li>尽量不适用<code>relative</code>，定位某元素，可以使用<strong>无依赖的绝对定位</strong>；</li><li>如果需要使用<code>relative</code>，则该<code>relative</code>需要最小化。  <pre><code>&lt;div&gt;
 &lt;div style=&quot;position:relative;&quot;&gt;
     &lt;img src=&quot;1.jpg&quot; alt=&quot;&quot; style=&quot;position: absolute;top: 0;right: 0;&quot;&gt;
 &lt;/div&gt;
 &lt;p&gt;内容1&lt;/p&gt;
 &lt;p&gt;内容2&lt;/p&gt;
&lt;/div&gt;
</code></pre></li></ol>
<h1 id="-position-fixed-">强悍的<code>position:fixed</code>固定定位</h1>
<h2 id="-position-fixed-"><code>position:fixed</code>不一样的“包含块”</h2>
<p><code>position:fixed</code>固定定位元素的<strong>包含块</strong>是根元素。唯一可以限制固定定位元素的是<code>&lt;html&gt;</code>根元素。<code>relative</code>对<code>fixed</code>定位没有任何限制作用。</p>
<p><p data-height="265" data-theme-id="0" data-slug-hash="EpQepP" data-default-tab="css,result" data-user="whjin" data-pen-title="无依赖固定定位" class="codepen">See the Pen <a href="https://codepen.io/whjin/pen/EpQepP/">无依赖固定定位</a> by whjin (<a href="https://codepen.io/whjin">@whjin</a>) on <a href="https://codepen.io">CodePen</a>.</p></p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<h2 id="-position-fixed-absolute-"><code>position:fixed</code>的<code>absolute</code>模拟</h2>
<pre><code>&lt;div class=&quot;page&quot;&gt;固定定位元素&lt;/div&gt;
&lt;div class=&quot;fixed&quot;&gt;&lt;/div&gt;
html, body {
    height: 100%;
    overflow: hidden;
}
.page {
    height: 100%;
    overflow: auto;
}
.fixed {
    position: absolute;
}
</code></pre><h2 id="-position-fixed-"><code>position:fixed</code>与背景锁定</h2>

</body>
</html>
<!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
